# 当前脚本来自于 http://script.345yun.cn 脚本库下载。
# 脚本库中的所有脚本文件均来自热心网友上传和互联网收集。
# 脚本库仅提供文件上传和下载服务，不提供脚本文件的审核。
# 您在使用脚本库下载的脚本时自行检查判断风险。
# 所涉及到的 账号安全、数据泄露、设备故障、软件违规封禁、财产损失等问题及法律风险，与脚本库无关！均由开发者、上传者、使用者自行承担。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
小当家自动化脚本 - 代理IP版本
全国流量卡免费领取
https://h5.lot-ml.com/ProductEn/Shop/44f3d0aed110f853
"""

print(r"""
◇◇◇◇◇◇◆◆◇◇◇◇◇◇◇◇◇◇◇◆◆◇◇◇◇◇◆◆◇◇
◇◇◇◇◇◇◇◆◆◇◇◇◇◇◇◇◇◇◇◆◆◇◆◇◇◇◆◆◇◇
◇◇◇◇◇◇◆◆◆◆◆◆◆◇◇◇◇◇◇◇◆◇◆◆◇◇◆◇◇◇
◇◇◆◆◆◆◆◆◆◆◆◆◆◇◇◇◇◇◇◇◆◇◇◆◇◇◆◇◇◇
◇◇◇◇◇◆◇◇◇◇◇◇◇◇◇◇◇◇◇◆◆◇◇◆◇◇◆◇◇◇
◇◇◇◇◇◆◇◇◆◆◆◇◇◇◇◇◇◇◇◆◆◇◇◆◇◇◆◇◇◇
◇◇◇◇◆◆◆◆◆◆◆◆◇◇◇◇◇◇◇◆◆◇◇◆◇◇◆◇◇◇
◇◇◇◇◇◆◇◆◆◇◆◆◇◇◇◇◇◇◇◆◆◇◇◆◇◇◆◇◇◇
◇◇◇◆◇◆◇◆◆◇◇◆◆◇◇◇◇◇◇◆◆◇◇◆◇◇◆◇◇◇
◇◇◆◆◇◆◆◇◇◆◆◇◆◇◇◇◇◇◆◆◇◇◆◆◇◇◆◇◇◇
◇◇◆◆◇◆◆◆◆◇◆◇◇◇◇◇◇◇◆◆◇◇◇◆◇◇◆◇◇◇
◇◇◆◇◇◇◇◆◆◆◆◆◇◇◇◇◇◆◆◇◇◇◇◇◇◇◆◇◇◇
◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◆◇◇◇◇◇◇◇◇◆◇◇◇
◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
全国流量卡免费领取
https://h5.lot-ml.com/ProductEn/Shop/44f3d0aed110f853
抓取任意链接的authorization填到变量XDJ里，多账号用&或者换行分割
3个账号以上必须加代理，代理名XDJ_API ，代理格式为JSON
请手动完成第一次任务，并保持开启消息通知否则任务失败
此脚本只为本群内部群员使用，未经允许禁止传播，一经发现后果自负。
如果你意外获得此脚本可联系忘川，举报传播者可代替他的位置
联系忘川 q: 3052221086 *付费进群，介意勿扰
""")

import os
import requests
import json
import time
import random
from typing import Dict, List, Optional

class ProxyManager:
    """代理IP管理器"""

    def __init__(self):
        self.proxy_api = os.environ.get('XDJ_API', '').strip()

    def get_proxy(self) -> Optional[Dict]:
        """获取代理IP - 每次都会重新获取"""
        if not self.proxy_api:
            return None

        try:
            # 每次都从API获取新的代理
            print(f"🔄 正在从代理API获取IP...")
            response = requests.get(self.proxy_api, timeout=10)
            if response.status_code == 200:
                data = response.json()
                proxy = None

                # 处理不同格式的代理API响应
                if isinstance(data, list) and len(data) > 0:
                    # 格式: [{"ip": "1.1.1.1", "port": 8080}, ...]
                    item = data[0]  # 只取第一个
                    proxy = {
                        'http': f"http://{item['ip']}:{item['port']}",
                        'https': f"http://{item['ip']}:{item['port']}"
                    }
                elif 'data' in data and isinstance(data['data'], list) and len(data['data']) > 0:
                    # 格式: {"code": 0, "data": [{"ip": "1.1.1.1", "port": 8080}, ...]}
                    item = data['data'][0]  # 只取第一个
                    proxy = {
                        'http': f"http://{item['ip']}:{item['port']}",
                        'https': f"http://{item['ip']}:{item['port']}"
                    }
                elif 'proxy' in data:
                    # 格式: {"proxy": "1.1.1.1:8080"}
                    ip_port = data['proxy']
                    proxy = {
                        'http': f"http://{ip_port}",
                        'https': f"http://{ip_port}"
                    }
                elif 'ip' in data and 'port' in data:
                    # 格式: {"ip": "1.1.1.1", "port": 8080}
                    proxy = {
                        'http': f"http://{data['ip']}:{data['port']}",
                        'https': f"http://{data['ip']}:{data['port']}"
                    }
                elif 'server' in data:
                    # 格式: {"server": "1.1.1.1:8080"}
                    ip_port = data['server']
                    proxy = {
                        'http': f"http://{ip_port}",
                        'https': f"http://{ip_port}"
                    }

                if proxy:
                    # 显示获取的代理IP
                    proxy_ip = self._extract_ip_from_proxy(proxy)
                    print(f"✅ 获取到代理IP: {proxy_ip}")
                    return proxy

            print("❌ 代理API响应异常")
            return None

        except Exception as e:
            print(f"❌ 获取代理失败: {str(e)}")
            return None

    def _extract_ip_from_proxy(self, proxy: Dict) -> str:
        """从代理字典中提取IP地址"""
        try:
            proxy_url = proxy.get('http', '') or proxy.get('https', '')
            if proxy_url:
                # 提取IP:PORT格式
                ip_port = proxy_url.replace('http://', '').replace('https://', '')
                return ip_port
        except:
            pass
        return "未知"

    def test_proxy(self, proxy: Dict) -> bool:
        """测试代理是否可用"""
        try:
            test_url = "http://httpbin.org/ip"
            response = requests.get(test_url, proxies=proxy, timeout=5)
            if response.status_code == 200:
                ip_info = response.json().get('origin', '未知')
                print(f"✅ 代理测试成功，当前IP: {ip_info}")
                return True
        except Exception as e:
            print(f"❌ 代理测试失败: {str(e)}")
        return False

class PushPlusNotifier:
    """PushPlus消息推送类"""

    def __init__(self, token: str):
        self.token = token
        self.url = "http://www.pushplus.plus/send"

    def send_notification(self, title: str, content: str) -> bool:
        """发送PushPlus通知"""
        if not self.token:
            print("❌ 未设置PushPlus Token，跳过消息推送")
            return False

        try:
            # 添加版权信息到内容底部
            copyright_info = """
<br><br>
<hr>
<p style="color: #666; font-size: 12px;">
摸鱼大队出品&nbsp;&nbsp;&nbsp;&nbsp;作者:忘川<br>
此脚本只为本群内部群员使用，未经允许禁止传播，一经发现后果自负。<br>
如果你意外获得此脚本可联系群主，举报传播者可代替他的位置<br>
偷撸群主q:3052221086*付费进，介意勿扰
</p>
"""
            content += copyright_info

            data = {
                "token": self.token,
                "title": title,
                "content": content,
                "template": "html"
            }

            headers = {'Content-Type': 'application/json'}
            response = requests.post(
                self.url, 
                data=json.dumps(data), 
                headers=headers,
                timeout=10
            )

            result = response.json()
            if result.get('code') == 200:
                print("✅ 执行结果已推送到微信")
                return True
            else:
                print(f"❌ 消息推送失败: {result.get('msg', '未知错误')}")
                return False

        except Exception as e:
            print(f"❌ 推送请求异常: {str(e)}")
            return False

class XiaoDangJia:
    def __init__(self, authorization: str, account_index: int, proxy_manager: ProxyManager = None):
        self.authorization = authorization.strip()
        self.account_index = account_index
        self.proxy_manager = proxy_manager
        self.current_proxy = None

        # 为每个账号生成不同的UA
        self.common_headers = self._generate_headers()

        self.common_payload = {
            "tmplIds": [
                "rgg3A6s4bqmguHkeg7eSiPztD5oDYquW3HndvRBrE9g",
                "2pEUegRHpR32HPMTryJpKRvbu_CPdko61lQtWHbpCKI",
                "xuLex1uYsiH0f_Y3Pt0_RpzwRZiR5Qp2J5GsxfWYsoE"
            ],
            "platform": 1
        }

        # 为每个账号获取新的代理IP
        if self.proxy_manager:
            self.current_proxy = self.proxy_manager.get_proxy()
            if self.current_proxy:
                proxy_ip = self.proxy_manager._extract_ip_from_proxy(self.current_proxy)
                print(f"🔄 为账号 {account_index} 分配代理IP: {proxy_ip}")

    def _generate_headers(self) -> Dict:
        """为每个账号生成不同的请求头"""
        # 不同版本的微信UA
        wechat_versions = [
            "7.0.20.1781(0x6700143B)",
            "7.0.21.1800(0x6700150C)", 
            "7.0.22.1820(0x6700160C)",
            "7.0.23.1840(0x6700170C)",
            "7.0.24.1860(0x6700180C)",
            "7.0.25.1880(0x6700190C)",
            "8.0.30.2220(0x67001E0C)",
            "8.0.31.2240(0x67001F0C)",
            "8.0.32.2260(0x6700200C)",
            "8.0.33.2280(0x6700210C)"
        ]

        # 不同设备型号
        device_models = [
            "Windows NT 10.0; Win64; x64",
            "Windows NT 10.0; WOW64", 
            "Windows NT 6.1; Win64; x64",
            "Windows NT 6.1; WOW64",
            "Windows NT 6.3; Win64; x64",
            "Windows NT 6.3; WOW64"
        ]

        # 不同Chrome版本
        chrome_versions = [
            "132.0.0.0",
            "131.0.0.0", 
            "130.0.0.0",
            "129.0.0.0",
            "128.0.0.0",
            "127.0.0.0",
            "126.0.0.0",
            "125.0.0.0"
        ]

        # 随机选择组件
        wechat_version = random.choice(wechat_versions)
        device_model = random.choice(device_models)
        chrome_version = random.choice(chrome_versions)

        # 生成唯一的UA
        user_agent = f"Mozilla/5.0 ({device_model}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{chrome_version} Safari/537.36 MicroMessenger/{wechat_version} NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541211) XWEB/16815"

        return {
            'User-Agent': user_agent,
            'appid': "xiaodangjia",
            'authorization': self.authorization,
            'xweb_xhr': "1",
            'content-type': "application/json",
            'sec-fetch-site': "cross-site",
            'sec-fetch-mode': "cors",
            'sec-fetch-dest': "empty",
            'referer': "https://servicewechat.com/wx7f5bc6f204abc629/19/page-frame.html",
            'accept-language': "zh-CN,zh;q=0.9",
            'priority': "u=1, i"
        }

    def _make_request(self, method: str, url: str, data: Dict = None, max_retries: int = 2) -> Dict:
        """统一的请求方法，支持代理和重试"""
        for attempt in range(max_retries + 1):
            try:
                kwargs = {
                    'headers': self.common_headers,
                    'timeout': 15
                }

                # 添加代理
                if self.current_proxy:
                    kwargs['proxies'] = self.current_proxy
                    proxy_ip = self.proxy_manager._extract_ip_from_proxy(self.current_proxy)
                    print(f"🌐 使用代理IP: {proxy_ip}")

                # 添加数据
                if data:
                    kwargs['data'] = json.dumps(data)

                if method.upper() == 'GET':
                    response = requests.get(url, **kwargs)
                else:
                    response = requests.post(url, **kwargs)

                return response.json()

            except requests.exceptions.ProxyError:
                print(f"❌ 代理连接失败，尝试 {'重试' if attempt < max_retries else '放弃'}")
                if attempt < max_retries and self.proxy_manager:
                    # 更换代理
                    self.current_proxy = self.proxy_manager.get_proxy()
                    time.sleep(2)
            except Exception as e:
                print(f"❌ 请求失败: {str(e)}，尝试 {'重试' if attempt < max_retries else '放弃'}")
                if attempt < max_retries:
                    time.sleep(2)

        return {"code": -1, "msg": "请求失败，已达到最大重试次数"}

    def sign_in(self) -> Dict:
        """执行签到任务"""
        url = "https://lm.api.sujh.net/app/score/sign"
        return self._make_request('POST', url, self.common_payload)

    def get_score_info(self) -> Dict:
        """执行积分查询任务"""
        url = "https://lm.api.sujh.net/app/score/index?platform=1"
        return self._make_request('GET', url)

def parse_accounts(env_value: str) -> List[str]:
    """解析多账号环境变量"""
    accounts = []
    if not env_value:
        return accounts

    # 多种分隔符支持
    separators = ['&', ' ', '|', ',', ';', '\n']

    for sep in separators:
        if sep in env_value:
            accounts = [acc.strip() for acc in env_value.split(sep) if acc.strip()]
            # 如果成功分割且找到有效账号，就停止尝试其他分隔符
            if accounts and len(accounts[0]) > 10:
                break

    # 如果没有找到分隔符，尝试直接使用
    if not accounts and len(env_value) > 10:
        accounts = [env_value.strip()]

    # 过滤掉长度过短的无效token
    accounts = [acc for acc in accounts if len(acc) > 10]

    return accounts

def format_push_content(accounts_count: int, success_count: int, total_score: float, details: List[Dict]) -> str:
    """格式化推送消息内容"""
    content = f"<b>🎉 小当家签到任务完成</b><br><br>"
    content += f"<b>📊 执行概览：</b><br>"
    content += f"• 账号总数: {accounts_count}<br>"
    content += f"• 成功处理: {success_count}<br>"
    content += f"• 成功比例: {success_count}/{accounts_count}<br>"
    content += f"• 累计积分: <b>{total_score}</b><br><br>"

    content += f"<b>📋 详细结果：</b><br>"
    for i, detail in enumerate(details, 1):
        content += f"<b>账号 {i}:</b><br>"
        content += f"• 签到: {detail['sign_status']}<br>"
        content += f"• 积分: {detail['score']}<br>"
        content += f"• 状态: {detail['sign_in_status']}<br>"
        if detail.get('proxy_used'):
            content += f"• 代理: {detail['proxy_used']}<br>"
        if detail.get('error'):
            content += f"• 错误: {detail['error']}<br>"
        content += f"<br>"

    content += f"<b>⏰ 执行时间：</b>{time.strftime('%Y-%m-%d %H:%M:%S')}<br>"
    return content

def process_single_account(account_index: int, auth: str, proxy_manager: ProxyManager) -> Dict:
    """处理单个账号的所有任务"""
    print(f"\n👤 正在处理第 {account_index} 个账号...")
    print(f"🔑 令牌: {auth[:20]}...{auth[-10:] if len(auth) > 30 else ''}")

    # 创建实例
    xdj = XiaoDangJia(auth, account_index, proxy_manager)

    detail = {
        'sign_status': '未知',
        'score': 0,
        'sign_in_status': '未知',
        'proxy_used': None,
        'error': None
    }

    # 记录使用的代理
    if xdj.current_proxy and proxy_manager:
        proxy_ip = proxy_manager._extract_ip_from_proxy(xdj.current_proxy)
        detail['proxy_used'] = proxy_ip

    try:
        # 打印当前使用的UA信息
        ua = xdj.common_headers['User-Agent']
        print(f"🛠️  使用UA: {ua.split('Chrome/')[1].split(' ')[0]}...")
        if xdj.current_proxy:
            print(f"🌐 使用代理: {detail['proxy_used']}")

        # 执行签到
        print("🔄 正在执行签到任务...")
        sign_result = xdj.sign_in()
        time.sleep(random.uniform(1, 2))  # 随机延迟1-2秒

        # 执行积分查询
        print("🔄 正在执行积分查询任务...")
        score_result = xdj.get_score_info()

        # 处理签到结果
        sign_code = sign_result.get('code')
        sign_msg = sign_result.get('msg', '')

        if sign_code == 200:
            detail['sign_status'] = f"✅ 成功 ({sign_msg})"
            print(f"✅ 签到成功: {sign_msg}")
        elif sign_code == 500 and "今日已签到" in sign_msg:
            detail['sign_status'] = "ℹ️ 今日已签到"
            print(f"ℹ️  今日已签到")
        else:
            detail['sign_status'] = f"❌ 失败 ({sign_msg})"
            print(f"❌ 签到失败: {sign_msg}")

        # 处理积分查询结果
        score_code = score_result.get('code')

        if score_code == 200:
            detail['score'] = score_result.get('data', {}).get('score', 0)
            sign_in_flag = score_result.get('data', {}).get('signIn', 0)
            detail['sign_in_status'] = '已签到' if sign_in_flag == 1 else '未签到'
            print(f"💰 当前积分: {detail['score']}")
            print(f"📝 签到状态: {detail['sign_in_status']}")
        else:
            print(f"❌ 积分查询失败: {score_result.get('msg', '未知错误')}")
            detail['sign_in_status'] = "查询失败"
            detail['error'] = score_result.get('msg', '未知错误')

    except Exception as e:
        error_msg = f"处理账号时发生异常: {str(e)}"
        print(f"❌ {error_msg}")
        detail['error'] = error_msg
        detail['sign_status'] = "❌ 异常"
        detail['sign_in_status'] = "❌ 异常"

    return detail

def main():
    """主函数"""
    print("\n" + "=" * 50)
    print("🔔 开始执行小当家自动化脚本")
    print("=" * 50)

    # 读取环境变量
    env_value = os.environ.get('XDJ', '').strip()
    pushplus_token = os.environ.get('PUSHPLUS_TOKEN', '').strip()
    proxy_api = os.environ.get('XDJ_API', '').strip()

    if not env_value:
        print("❌ 未找到环境变量 XDJ")
        return

    # 初始化代理管理器
    proxy_manager = None
    if proxy_api:
        print("🔄 初始化代理管理器...")
        proxy_manager = ProxyManager()
        # 测试代理
        test_proxy = proxy_manager.get_proxy()
        if test_proxy and proxy_manager.test_proxy(test_proxy):
            print("✅ 代理服务可用")
        else:
            print("❌ 代理服务不可用，将使用直连")
            proxy_manager = None
    else:
        print("ℹ️  未设置XDJ_API，将使用直连")

    # 初始化推送器
    notifier = PushPlusNotifier(pushplus_token)

    # 解析账号
    accounts = parse_accounts(env_value)
    if not accounts:
        print("❌ 未找到有效的授权令牌")
        print("💡 请检查XDJ环境变量格式，支持 & 空格 | , ; 换行 等分隔符")
        return

    print(f"📝 找到 {len(accounts)} 个账号")
    print(f"🛠️  将为每个账号生成不同的UA模拟不同设备")
    if proxy_manager:
        print(f"🌐 已启用代理IP服务 - 每个账号使用独立IP")
    if pushplus_token:
        print(f"🔔 已启用PushPlus消息推送")
    else:
        print("ℹ️  未设置PUSHPLUS_TOKEN，跳过消息推送")
    print("=" * 50)

    success_count = 0
    total_score = 0
    details = []

    # 遍历所有账号
    for i, auth in enumerate(accounts, 1):
        detail = process_single_account(i, auth, proxy_manager)
        details.append(detail)

        # 如果处理成功且没有错误，计数成功
        if not detail.get('error') and detail['sign_in_status'] != '❌ 异常':
            success_count += 1
            total_score += detail['score']

        # 添加随机延迟，避免请求过快被限制
        if i < len(accounts):
            delay = random.uniform(3, 5)  # 3-5秒随机延迟
            print(f"⏳ 等待 {delay:.1f} 秒后处理下一个账号...")
            time.sleep(delay)

    # 汇总结果
    print("\n" + "=" * 50)
    print("📊 任务执行完成")
    print(f"✅ 成功处理: {success_count}/{len(accounts)} 个账号")
    if success_count > 0:
        print(f"💰 总积分: {total_score}")
    print("🎉 脚本执行结束")

    # 发送推送通知
    if pushplus_token and success_count > 0:
        print("\n🔄 正在发送微信通知...")
        title = f"小当家签到完成 - 成功{success_count}/{len(accounts)}"
        content = format_push_content(len(accounts), success_count, total_score, details)
        notifier.send_notification(title, content)

if __name__ == "__main__":
    main()

# 当前脚本来自于 http://script.345yun.cn 脚本库下载。
# 脚本库中的所有脚本文件均来自热心网友上传和互联网收集。
# 脚本库仅提供文件上传和下载服务，不提供脚本文件的审核。
# 您在使用脚本库下载的脚本时自行检查判断风险。
# 所涉及到的 账号安全、数据泄露、设备故障、软件违规封禁、财产损失等问题及法律风险，与脚本库无关！均由开发者、上传者、使用者自行承担。